﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using DTO;

namespace DAO
{
    public class VocabularyDAO
    {
        public static List<VOCABULARY> getListVocabularies()
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    res.Add(tempVocabulary);
                }                                    
            }
            catch (Exception ex)
            {
                throw ex;
            }            
            return res;
        }

        public static List<VOCABULARY> getListVocabularies(short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.isTwoWordVerb == isTwoWordVerb)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }        
            return res;
        }

        public static List<VOCABULARY> getListVocabularies(int idTopic)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.idTopic == idTopic)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabularies(int idTopic, short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.idTopic == idTopic
                        && tempVocabulary.isTwoWordVerb == idTopic)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static VOCABULARY getVocabulary(String word, String type, int idTopic)
        {            
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return null;
                }
                
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Word.Equals(word) && tempVocabulary.Type.Equals(type)
                        && tempVocabulary.idTopic == idTopic)
                    {
                        return tempVocabulary;                        
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }        
            return null;
        }
        
        public static List<VOCABULARY> getListVocabulariesbyDateToDate(DateTime dateBegin, DateTime dateEnd)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Date >= dateBegin.Date
                        && tempVocabulary.Date.Date <= dateEnd.Date)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyDateToDate(DateTime dateBegin, DateTime dateEnd, int idTopic)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Date >= dateBegin.Date
                        && tempVocabulary.Date.Date <= dateEnd.Date
                        && tempVocabulary.idTopic == idTopic)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyDateToDate(DateTime dateBegin, DateTime dateEnd, short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Date >= dateBegin.Date
                        && tempVocabulary.Date.Date <= dateEnd.Date
                        && tempVocabulary.isTwoWordVerb == isTwoWordVerb)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyDateToDate(DateTime dateBegin, DateTime dateEnd, int idTopic, short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Date >= dateBegin.Date
                        && tempVocabulary.Date.Date <= dateEnd.Date
                        && tempVocabulary.idTopic == idTopic
                        && tempVocabulary.isTwoWordVerb == isTwoWordVerb)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyMonth(DateTime date)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Month == date.Month)                        
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyMonth(DateTime date, int idTopic)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Month == date.Month
                        && tempVocabulary.idTopic == idTopic)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyMonth(DateTime date, short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Month == date.Month
                        && tempVocabulary.isTwoWordVerb == isTwoWordVerb)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListVocabulariesbyMonth(DateTime date, int idTopic, short isTwoWordVerb)
        {
            List<VOCABULARY> res = null;
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return res;
                }

                res = new List<VOCABULARY>();
                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    tempVocabulary.LoadVocabulary(nodeVocabularies[i]);
                    if (tempVocabulary.Date.Month == date.Month
                        && tempVocabulary.isTwoWordVerb == isTwoWordVerb
                        && tempVocabulary.idTopic == idTopic)
                    {
                        res.Add(tempVocabulary);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListRandVocabularies(int nWord)
        {
            List<VOCABULARY> res = new List<VOCABULARY>();
            try
            {
                List<VOCABULARY> ListVocabularies = getListVocabularies();
                List<int> indexRandom = new List<int>();
                Random rd = new Random();
                while (res.Count < nWord)
                {
                    int indexTemp = rd.Next(0, ListVocabularies.Count - 1);
                    if (!indexRandom.Contains(indexTemp))
                    {
                        res.Add(ListVocabularies[indexTemp]);
                        indexRandom.Add(indexTemp);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListRandVocabularies(int nWord, int idTopic)
        {
            List<VOCABULARY> res = new List<VOCABULARY>();
            try
            {
                List<VOCABULARY> ListVocabularies = getListVocabularies(idTopic);
                List<int> indexRandom = new List<int>();
                Random rd = new Random();
                while (res.Count < nWord)
                {
                    int indexTemp = rd.Next(0, ListVocabularies.Count - 1);
                    if (!indexRandom.Contains(indexTemp))
                    {
                        res.Add(ListVocabularies[indexTemp]);
                        indexRandom.Add(indexTemp);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListRandVocabularies(int nWord, short isTwoWordVerb)
        {
            List<VOCABULARY> res = new List<VOCABULARY>();
            try
            {
                List<VOCABULARY> ListVocabularies = getListVocabularies(isTwoWordVerb);
                List<int> indexRandom = new List<int>();
                Random rd = new Random();
                while (res.Count < nWord)
                {
                    int indexTemp = rd.Next(0, ListVocabularies.Count - 1);
                    if (!indexRandom.Contains(indexTemp))
                    {
                        res.Add(ListVocabularies[indexTemp]);
                        indexRandom.Add(indexTemp);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static List<VOCABULARY> getListRandVocabularies(int nWord, int idTopic, short isTwoWordVerb)
        {
            List<VOCABULARY> res = new List<VOCABULARY>();
            try
            {
                List<VOCABULARY> ListVocabularies = getListVocabularies(idTopic, isTwoWordVerb);
                List<int> indexRandom = new List<int>();
                Random rd = new Random();
                while (res.Count < nWord)
                {
                    int indexTemp = rd.Next(0, ListVocabularies.Count - 1);
                    if (!indexRandom.Contains(indexTemp))
                    {
                        res.Add(ListVocabularies[indexTemp]);
                        indexRandom.Add(indexTemp);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return res;
        }

        public static bool Add(VOCABULARY vc)
        {            
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNode nodeVocabularies = xmlDoc.SelectSingleNode("MyVocabularies//Vocabularies");

                if (nodeVocabularies == null)
                {
                    return false;
                }

                XmlNode nodeVcNew = xmlDoc.CreateElement("Vocabulary");
                XmlNode nodeTemp;
                nodeTemp = xmlDoc.CreateElement("Word");
                nodeTemp.InnerText = vc.Word;
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("Type");
                nodeTemp.InnerText = vc.Type;
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("idTopic");
                nodeTemp.InnerText = vc.idTopic.ToString();
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("TopicDisplay");
                nodeTemp.InnerText = vc.TopicDisplay;
                nodeVcNew.AppendChild(nodeTemp);
                        
                nodeTemp = xmlDoc.CreateElement("Phoneticize");
                nodeTemp.InnerText = vc.Phoneticize;
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("MeanEng");
                nodeTemp.InnerText = vc.MeanEng;
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("MeanVi");
                nodeTemp.InnerText = vc.MeanVi;
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("Date");
                nodeTemp.InnerText = vc.Date.ToString();
                nodeVcNew.AppendChild(nodeTemp);

                nodeTemp = xmlDoc.CreateElement("isTwoWordVerb");
                nodeTemp.InnerText = vc.isTwoWordVerb.ToString();
                nodeVcNew.AppendChild(nodeTemp);

                nodeVocabularies.AppendChild(nodeVcNew);
                xmlDoc.Save(GlobalShare.pathDatabase);
                return true;
            }
            catch (Exception e)
            {
                throw e;                
            }            
        }

        public static bool Edit(String word, String type, int idTopic, VOCABULARY vcUpdate)
        {            
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return false;
                }

                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    XmlNode nodeOldVc = nodeVocabularies[i];
                    tempVocabulary.LoadVocabulary(nodeOldVc);
                    if (tempVocabulary.Word.Equals(word) && tempVocabulary.Type.Equals(type)
                        && tempVocabulary.idTopic == idTopic)
                    {
                        XmlNode nodeTemp;
                        nodeTemp = nodeOldVc.SelectSingleNode("Word");
                        nodeTemp.InnerText = vcUpdate.Word;

                        nodeTemp = nodeOldVc.SelectSingleNode("Type");
                        nodeTemp.InnerText = vcUpdate.Type;

                        nodeTemp = nodeOldVc.SelectSingleNode("idTopic");
                        nodeTemp.InnerText = vcUpdate.idTopic.ToString();

                        nodeTemp = nodeOldVc.SelectSingleNode("TopicDisplay");
                        nodeTemp.InnerText = vcUpdate.TopicDisplay;
                                                
                        nodeTemp = nodeOldVc.SelectSingleNode("Phoneticize");
                        nodeTemp.InnerText = vcUpdate.Phoneticize;

                        nodeTemp = nodeOldVc.SelectSingleNode("MeanEng");
                        nodeTemp.InnerText = vcUpdate.MeanEng;

                        nodeTemp = nodeOldVc.SelectSingleNode("MeanVi");
                        nodeTemp.InnerText = vcUpdate.MeanVi;

                        nodeTemp = nodeOldVc.SelectSingleNode("Date");
                        nodeTemp.InnerText = vcUpdate.Date.ToString();

                        nodeTemp = nodeOldVc.SelectSingleNode("isTwoWordVerb");
                        nodeTemp.InnerText = vcUpdate.isTwoWordVerb.ToString();
                        xmlDoc.Save(GlobalShare.pathDatabase);
                        return true;
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return false;
        }

        public static bool Remove(VOCABULARY vc)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(GlobalShare.pathDatabase);

                XmlNodeList nodeVocabularies = xmlDoc.GetElementsByTagName("Vocabulary");
                if (nodeVocabularies.Count <= 0)
                {
                    return false;
                }

                for (int i = 0; i < nodeVocabularies.Count; i++)
                {
                    VOCABULARY tempVocabulary = new VOCABULARY();
                    XmlNode nodeTemp = nodeVocabularies[i];
                    tempVocabulary.LoadVocabulary(nodeTemp);
                    if (tempVocabulary.Word.Equals(vc.Word) && tempVocabulary.Type.Equals(vc.Type)
                        && tempVocabulary.idTopic == vc.idTopic)
                    {
                        nodeTemp.ParentNode.RemoveChild(nodeTemp);
                        xmlDoc.Save(GlobalShare.pathDatabase);
                        return true;
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return false;
        }
    }
}
